package com.ideal.security.conf;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.security.UserGroupInformation.HadoopLoginModule;
import org.apache.hadoop.security.authentication.util.KerberosUtil;

import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import javax.security.auth.login.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 * 本类的目的是为krb5的pwd方式认证principal提供configuration，再叠加上OSLOGIN和HADOOPLOGIN
 * 本类地位等同于HadoopConfiguration
 * 
 * @author Think
 * 
 */
public class IdealHadoopConfiguration extends Configuration {

	static Log LOG = LogFactory.getLog(IdealHadoopConfiguration.class);

	private static final String PWD_KERBEROS_CONFIG_NAME = "hadoop-user-kerberos";
	private static String OS_LOGIN_MODULE_NAME;

	private static final boolean windows = System.getProperty("os.name")
			.startsWith("Windows");
	private static final boolean is64Bit = System.getProperty("os.arch")
			.contains("64");
	private static final boolean aix = System.getProperty("os.name").equals(
			"AIX");

	/**
	 * The java vendor name used in this platform.
	 */
	public static final String JAVA_VENDOR_NAME = System
			.getProperty("java.vendor");

	/**
	 * A public static variable to indicate the current java vendor is IBM java
	 * or not.
	 */
	public static final boolean IBM_JAVA = JAVA_VENDOR_NAME.contains("IBM");

	/* Return the OS login module class name */
	private static String getOSLoginModuleName() {
		if (IBM_JAVA) {
			if (windows) {
				return is64Bit ? "com.ibm.security.auth.module.Win64LoginModule"
						: "com.ibm.security.auth.module.NTLoginModule";
			} else if (aix) {
				return is64Bit ? "com.ibm.security.auth.module.AIX64LoginModule"
						: "com.ibm.security.auth.module.AIXLoginModule";
			} else {
				return "com.ibm.security.auth.module.LinuxLoginModule";
			}
		} else {
			return windows ? "com.sun.security.auth.module.NTLoginModule"
					: "com.sun.security.auth.module.UnixLoginModule";
		}
	}

	static {
		OS_LOGIN_MODULE_NAME = getOSLoginModuleName();
	}

	private static final Map<String, String> BASIC_JAAS_OPTIONS = new HashMap<String, String>();
	static {
		String jaasEnvVar = System.getenv("HADOOP_JAAS_DEBUG");
		if (jaasEnvVar != null && "true".equalsIgnoreCase(jaasEnvVar)) {
			BASIC_JAAS_OPTIONS.put("debug", "true");
		}
	}

	private static final AppConfigurationEntry OS_SPECIFIC_LOGIN = new AppConfigurationEntry(
			OS_LOGIN_MODULE_NAME, LoginModuleControlFlag.REQUIRED,
			BASIC_JAAS_OPTIONS);
	private static final AppConfigurationEntry HADOOP_LOGIN = new AppConfigurationEntry(
			HadoopLoginModule.class.getName(), LoginModuleControlFlag.REQUIRED,
			BASIC_JAAS_OPTIONS);

	private final static Map<String, String> PWD_KERBEROS_OPTIONS = new HashMap<String, String>();
	static {
		//PWD_KERBEROS_OPTIONS.put("doNotPrompt", "false");
		PWD_KERBEROS_OPTIONS.put("storeKey", "false");
		//PWD_KERBEROS_OPTIONS.put("renewTGT", "false");
		//PWD_KERBEROS_OPTIONS.put("useKeyTab", "false");
		PWD_KERBEROS_OPTIONS.put("useTicketCache", "false");
	}
	private final AppConfigurationEntry USER_KERBEROS_LOGIN = new AppConfigurationEntry(
			KerberosUtil.getKrb5LoginModuleName(),
			LoginModuleControlFlag.OPTIONAL, PWD_KERBEROS_OPTIONS);

	private final AppConfigurationEntry[] PWD_KERBEROS_CONF = new AppConfigurationEntry[] {
			OS_SPECIFIC_LOGIN, USER_KERBEROS_LOGIN, HADOOP_LOGIN };

	@Override
	public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
		if (PWD_KERBEROS_CONFIG_NAME.equals(name)) {
			return PWD_KERBEROS_CONF;
		}
		return null;
	}

	public void setPrincipal(String principal) {
		PWD_KERBEROS_OPTIONS.put("principal", principal);
	}

}
